﻿'Copyright (C) 2010  Thomas Huebner
'
'This program is free software
'
'you can redistribute it and/or modify it under the terms 
'of the GNU General Public License as published by the 
'Free Software Foundation either version 2 of the License, 
'or (at your option) any later version.
'
'This program is distributed in the hope that it will be 
'useful, but WITHOUT ANY WARRANTY without even the implied 
'warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
'See the GNU General Public License for more details.
'
'You should have received a copy of the GNU General Public License 
'along with this program; if not, write to the 
'Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
'Boston, MA 02111-1307, USA. 


Imports System.Net
Imports System.Text
Imports LFNETApi

Public Class Form1

    Private oConnection As LF_Connect

    ''' <summary>
    ''' BaseURL for Liquid Feedback
    ''' </summary>
    ''' <remarks></remarks>
    Private _BaseURL As String

    ''' <summary>
    ''' Personal Token for Liquid Feedback
    ''' </summary>
    ''' <remarks></remarks>
    Private _Token As String

    ''' <summary>
    ''' Dictionary for fast indexing treenodes
    ''' </summary>
    ''' <remarks></remarks>
    Private _Nodes As Dictionary(Of String, TreeNode)


    Private Sub cmd_Refresh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmd_Refresh.Click

        'avoid flicker
        trv_Overview.BeginUpdate()

        'clear treeview
        trv_Overview.Nodes.Clear()

        'clear dictionary used to fast indexing of treenodes
        Me._Nodes = New Dictionary(Of String, TreeNode)

        'check textboxes for base URL and Token
        If String.IsNullOrEmpty(tbo_baseURL.Text) Or String.IsNullOrEmpty(tbo_token.Text) Then
            MsgBox("Please enter Base URL and Token first", MsgBoxStyle.Critical, "Usererror")
            Exit Sub
        End If

        'store textbox content in private variables
        Me._BaseURL = tbo_baseURL.Text
        Me._Token = tbo_token.Text

        'Create new instance of connector (LFAPI)
        Me.oConnection = New LF_Connect(Me._BaseURL, Me._Token)

        'Get all Areas
        If oConnection.GetAllAreas Then

            'Iterate the Areas
            For Each oLFArea As LFNETApi.LF_Area In oConnection.Areas.items

                'Create Treenode for Area
                Dim nArea As New TreeNode(oLFArea.Name)
                nArea.Tag = oLFArea.ID
                nArea.ImageIndex = 0

                'Add node to treeview
                trv_Overview.Nodes.Add(nArea)

                'Add node to dictionary
                Me._Nodes.Add("area" & oLFArea.ID, nArea)

            Next

        Else
            MsgBox("Error loading Areas from LF", MsgBoxStyle.Critical, "API Error")
            Exit Sub
        End If

        'Create a parameterobject
        Dim param As New LF_Parameters(LF_Parameters.RequestType.Initiative, Me._BaseURL, Me._Token)

        'Initiatives part of LF Api supports HTML output
        'so we add this parameter
        param.AddParameter("render_draft", "html")

        'Get all initiatives
        If oConnection.GetInitiatives(param) Then

            'iterate the initiatives
            For Each oLFInitiative As LF_Initiative In oConnection.Initiatives.items

                'create Treenode for initiative
                Dim nInitiative As New TreeNode(oLFInitiative.Name & " (" & oLFInitiative.IssueState.ToString & ")")
                nInitiative.Tag = "initiative" & oLFInitiative.ID
                nInitiative.ImageIndex = 1

                'Colorize nodetext depending on issuestate
                If Not oLFInitiative.IssueState = "finished" And Not oLFInitiative.IssueState = "cancelled" Then
                    nInitiative.ForeColor = Color.Green
                Else
                    nInitiative.ForeColor = Color.Red
                End If

                'We need a Step in between because we have the issue as properties
                'in each initiative. Maybe Api developers will change that in a way
                'that initiatives are a list of childs in Issue

                'Looking whether we already have this issue in dictionary
                If Not Me._Nodes.ContainsKey("issue" & oLFInitiative.IssueID) Then

                    '... we haven't, so we create a new treenode for this issue
                    Dim nIssue As New TreeNode("Thema #" & oLFInitiative.IssueID)

                    'Adding the Issue node to Area node
                    Me._Nodes("area" & oLFInitiative.AreaID).Nodes.Add(nIssue)

                    'Adding the issue node to dictionary
                    Me._Nodes.Add("issue" & oLFInitiative.IssueID, nIssue)

                End If

                'Now we can be sure to have the Issue node and add the Initiative node
                Me._Nodes("issue" & oLFInitiative.IssueID).Nodes.Add(nInitiative)

                'Add the Initiative node to dictionary too
                Me._Nodes.Add("initiative" & oLFInitiative.ID, nInitiative)

            Next
        Else
            MsgBox("Error loading Initiatives from LF", MsgBoxStyle.Critical, "API Error")
            Exit Sub
        End If

        'Get all Suggestions
        If oConnection.GetAllSuggestions Then

            'Iterate the Suggestions
            For Each oLFSuggestion As LF_Suggestion In oConnection.Suggestions.items

                'Create a treenode for suggestion
                Dim nSuggestion As New TreeNode(oLFSuggestion.Name)
                nSuggestion.ImageIndex = 2
                nSuggestion.Tag = "suggestion" & oLFSuggestion.ID

                'Check whether the Initiative for this Suggestion is in dictionary
                If Me._Nodes.ContainsKey("initiative" & oLFSuggestion.InitiativeID) Then

                    'Add Suggestion node to Initiative node
                    Me._Nodes("initiative" & oLFSuggestion.InitiativeID).Nodes.Add(nSuggestion)

                    'Add Suggestion node to Dictionary
                    Me._Nodes.Add("suggestion" & oLFSuggestion.ID, nSuggestion)

                End If
            Next
        Else
            MsgBox("Error loading Suggestions from LF", MsgBoxStyle.Critical, "API Error")
            Exit Sub
        End If

        'Reactivate screenupdating
        trv_Overview.EndUpdate()

    End Sub

    Private Sub trv_Overview_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles trv_Overview.AfterSelect

        If Not trv_Overview.SelectedNode Is Nothing Then
            FillInitiative()
        End If

    End Sub


    Private Sub FillInitiative()

        With trv_Overview

            'do not change the icon of expanded node
            .SelectedImageIndex = .SelectedNode.ImageIndex

            'Check we have an Initiative in Level2
            If .SelectedNode.Level = 2 Then

                'Iterate the Initiatives to find the selected one
                For Each oLFInitiative As LF_Initiative In oConnection.Initiatives.items
                    If .SelectedNode.Tag = "initiative" & oLFInitiative.ID Then

                        'Fill the Browsercontrol with Initiative Description (HTML)
                        wbr_Content.DocumentText = oLFInitiative.CurrentDraftContent

                        'Parse Dates and fill the Calendar listview
                        FillCalendarView(oLFInitiative)

                        'Set rest of GUI with some properties of initiative
                        SetGui(oLFInitiative)

                        'Leave the loop after found
                        Exit For
                    End If
                Next

                'Check we have a Suggestion in Level3
            ElseIf .SelectedNode.Level = 3 Then

                'iterate the Suggestions to pick the selected
                For Each oLFSuggestion As LF_Suggestion In oConnection.Suggestions.items
                    If .SelectedNode.Tag = "suggestion" & oLFSuggestion.ID Then

                        'Fill Browsercontrol with Suggestion description
                        wbr_Content.DocumentText = oLFSuggestion.Description

                        'Leave the loop after found
                        Exit For
                    End If
                Next
            End If

        End With 'trv_Overview

    End Sub

    Private Sub FillCalendarView(ByRef Initiative As LF_Initiative)

        'clear the Listview
        lvw_Calendar.Items.Clear()

        'we set 5 Dates
        For i As Integer = 0 To 4

            Dim litem As New ListViewItem

            'Default is icon 1
            litem.ImageIndex = 1

            'Set the different Dates
            'I don't know whether the calculation is right but in each
            'case it should work dynamically if dates change later
            Select Case i
                Case 0
                    litem.Text = "Created"
                    If DateDiff(DateInterval.Minute, Initiative.IssueCreated, Date.Now) > 0 Then
                        litem.ImageIndex = 0
                    End If
                    litem.SubItems.Add(Initiative.IssueCreated.ToString)
                Case 1
                    litem.Text = "Accepted"
                    If DateDiff(DateInterval.Minute, Initiative.IssueAccepted, Date.Now) > 0 Then
                        litem.ImageIndex = 0
                    End If
                    litem.SubItems.Add(Initiative.IssueAccepted.ToString)
                Case 2
                    litem.Text = "Half Frozen"
                    If DateDiff(DateInterval.Minute, Initiative.IssueHalfFrozen, Date.Now) > 0 Then
                        litem.ImageIndex = 0
                    End If
                    litem.SubItems.Add(Initiative.IssueHalfFrozen.ToString)
                Case 3
                    litem.Text = "Full Frozen"
                    If DateDiff(DateInterval.Minute, Initiative.IssueFullyFrozen, Date.Now) > 0 Then
                        litem.ImageIndex = 0
                    End If
                    litem.SubItems.Add(Initiative.IssueFullyFrozen.ToString)
                Case 4
                    litem.Text = "Closed"
                    If DateDiff(DateInterval.Minute, Initiative.IssueClosed, Date.Now) > 0 Then
                        litem.ImageIndex = 0
                    End If
                    litem.SubItems.Add(Initiative.IssueClosed.ToString)
            End Select

            'Add the prepared item to listview
            lvw_Calendar.Items.Add(litem)

        Next
    End Sub

    Private Sub SetGui(ByRef Initiative As LF_Initiative)

        'Set population label
        lbl_population.Text = Initiative.IssuePopulation

        'Set votes label
        lbl_quote.Text = String.Format("{0}/{1}", Initiative.PositiveVotes, Initiative.NegativeVotes)

        'Very bad way to calculate the number of suggestions of an Initiative XD
        Dim iSuggestionCount As Integer = 0
        For Each oLFSuggestion As LF_Suggestion In oConnection.Suggestions.items
            If oLFSuggestion.InitiativeID = Initiative.ID Then
                iSuggestionCount += 1
            End If
        Next
        lbl_suggestions.Text = iSuggestionCount

        'Check we have a link (URL) for discussion and switch on/off the label
        If Not String.IsNullOrEmpty(Initiative.DiscussionURL) Then
            lbl_Discussion.Tag = Initiative.DiscussionURL
            lbl_Discussion.Enabled = True
        Else
            lbl_Discussion.Tag = Initiative.DiscussionURL
            lbl_Discussion.Enabled = False
        End If

    End Sub

    Private Sub lbl_Discussion_LinkClicked(ByVal sender As System.Object, _
                                           ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) _
                                           Handles lbl_Discussion.LinkClicked

        'Calling the discussion webpage in standardbrowser (external process)
        If Not String.IsNullOrEmpty(lbl_Discussion.Tag) Then
            Process.Start(lbl_Discussion.Tag)
        End If

    End Sub

End Class
